package UIPhoto
{
	import UIFree.ObjectEvent;
	import UIFree.uif_component;
	import UIFree.uif_ecomponent;
	
	import UIUtils.uif_matrix;
	import UIUtils.uif_util;
	
	import flash.display.Bitmap;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class new_uip_rect extends uif_ecomponent {
		private var _ctrlResize	: uip_ctrlHandle;
		private var _ctrlRoll	: uip_ctrlHandle;
		
		private var _pResize	: Point;
		private var _pRoll		: Object;
		protected var _photoRect	: Rectangle;
		
		public function uip_rect(parent: uip_photoEditor, images: Object, styleClass: String ='selectRect') {
			super(parent, 0, 0, 50, 50, styleClass);
			buttonMode = true;
			/*alpha = 0;
			addEvent(MouseEvent.ROLL_OVER, doOver, parent);*/
			addEvent(MouseEvent.ROLL_OUT, doOut, parent);
			addEvent(MouseEvent.MOUSE_DOWN, doDown);
			
//			addEvent(uip_events.UPDATECONTENT, doUpdateFromPhoto, app);
			addEvent(MouseEvent.MOUSE_UP, doCRUp, wrapper);
			addEvent(MouseEvent.MOUSE_MOVE, doCRMove, wrapper);
			addEvent(uif_component.DRAG, doDrag);
			
			_ctrlResize = new uip_ctrlHandle(this, images.c_resize, doCRDown);
			_ctrlRoll 	= new uip_ctrlHandle(this, images.c_roll, doRLDown);
			visible 	= false;
			
//			if (app.photosLoaded) doUpdateFromPhoto();			
		}
		
		
		protected function get wrapper(): EventDispatcher {
			return app;
		}
		
		protected function updateCtrlRect(): void {
			_ctrlResize.x = width - 10;
			_ctrlResize.y = height - 10;
			
			_ctrlRoll.x = width - 10;
			_ctrlRoll.y = -10
		}
		
/*		public function doUpdateFromPhoto(e: Event = null): void {
			if (image.matrix.getScale() > 1) 
				image.dispatchEvent(new ObjectEvent(uip_events.SCALE_RECT, 0));
			app.dispatchEvent(new ObjectEvent(uip_events.GET_POS, this));
		}*/
		
		public function get image(): uip_photoEditor {
			return parent as uip_photoEditor;
		}
		
		protected function get photo(): Bitmap {
			return image.photo;
		}
		
		public function setPos(mat: Matrix, contentSize: Point): void {
			var rect: Rectangle;
			
			if (photo != null) { 
				image.resetPhoto();
				mat.invert();
				_photoRect = new Rectangle(0, 0, contentSize.x, contentSize.y);
				
//				rect = image.EnterHere(contentSize);
				
				var irect: Rectangle = image.EnterHerePhoto();
				rect = uif_util.EnterHere(irect, contentSize);
				_photoRect = rect;
/*				mat.concat(image.matrix);
				mat.scale(photo.bitmapData.width/contentSize.x, photo.bitmapData.height/contentSize.y);
				mat.scale(irect.width / photo.bitmapData.width, irect.height / photo.bitmapData.height);
				
				rect.topLeft 		= mat.transformPoint(rect.topLeft);
				rect.bottomRight	= mat.transformPoint(rect.bottomRight);
				
				rect.offset(irect.x, irect.y);*/
				
				
				transform.matrix = new Matrix();
				position	= rect.topLeft;
				resize(rect.width, rect.height);
				updateCtrlRect();
				visible 	= true;
				setPosNotify();
			}
		}
		
		public function getPosMatrix(): uif_matrix {
			var irect	: Rectangle 	= image.EnterHerePhoto();
			var mat		: uif_matrix	= new uif_matrix();//transform.matrix;
			
			mat.scale(width / _photoRect.width, height / _photoRect.height);
			mat.concat(transform.matrix);
			mat.translate(-irect.x, -irect.y);
			mat.scale(photo.bitmapData.width / irect.width, photo.bitmapData.height / irect.height);
			
			var mi: Matrix = image.matrix.clone();
			mi.invert();
			mat.concat(mi);
			mat.invert();
			return mat; 
		}
		
		public function get editing(): Boolean {
			return !((_pResize == null) && (_pRoll == null))
		}
		
/*		protected function doOver(e: MouseEvent): void {
			fx('alpha', alpha, 1).start();
		}*/ 

		protected function doOut(e: MouseEvent): void {
			if (!editing) {
//				fx('alpha', alpha, 0).start();
				endDrag();
			}
		}
		
		protected function doDown(e: MouseEvent): void {
			if (!editing) 
				beginDrag(1, 1/image.matrix.getScale());
		}
		
		private function curCoordinates(): Object {
			var a_center: Point = transform.matrix.transformPoint(new Point(width / 2, height / 2));
			var a_pos: Point = transform.matrix.transformPoint(new Point(mouseX, mouseY));
			return {center: a_center, pos: a_pos};
		}
		
		protected function doCRDown(e: MouseEvent): void {
			_pResize = new Point(parent.mouseX, parent.mouseY);
		}
		
		protected function doRLDown(e: MouseEvent): void {
			var a_center: Point = transform.matrix.transformPoint(new Point(width / 2, height / 2));
			var a_pos: Point = transform.matrix.transformPoint(new Point(mouseX, mouseY));
			_pRoll = {center: a_center, pos: a_pos};
		}
		
		protected function minSize(): Number {
			return image.size.length * 0.3;
		}
		
		protected function doCRMove(e: MouseEvent): void {
			var cur			: Point;
			var pdec		: Point;
			var rect		: Rectangle;
			var dec			: Number = 0;
			if (_pResize != null) {
				var center: Point 	= parent.globalToLocal(localToGlobal(new Point(width / 2, height / 2)));
				cur					= new Point(parent.mouseX, parent.mouseY);
				pdec 				= _pResize.subtract(cur);
				var prevRect	: Rectangle = getOuter();
				rect = prevRect.clone();
				
				var v: Point = center.subtract(cur);
				dec = (Point.distance(cur, center) - Point.distance(_pResize as Point, center));
				
/*				dec = pdec.length * 0.66;
				if (pdec.y + pdec.x > 0) dec = -dec;*/
				
				function newRect(scale: Number): Rectangle {
					var mat	: uif_matrix = new uif_matrix();
					mat.translate(-center.x, -center.y);
					mat.scale(scale, scale);
					mat.translate(center.x, center.y);
					return mat.transformRect(rect);
				}
				
				var tmp: Rectangle = newRect((prevRect.width + dec) / prevRect.width);
				
				if (tmp.width > 0) {
					var iscale: Number = image.matrix.getScale();
					if (((tmp.bottomRight.subtract(tmp.topLeft).length > minSize()) && (iscale <= 1)) ||
						((iscale <= 1) && (dec > 0))) {
						position = tmp.topLeft;
						resize(tmp.width, tmp.height);
						updateCtrlRect();
					} else {
						_pResize = null;
						image.dispatchEvent(new ObjectEvent(uip_events.SCALE_RECT, dec * 0.5));
					}
					setPosNotify();
				}
				_pResize = cur;
				
			} else if (_pRoll != null) {
				var v1: Point = _pRoll.center.subtract(_pRoll.pos);
				_pRoll.pos = new Point(parent.mouseX, parent.mouseY);
				var v2: Point = _pRoll.center.subtract(_pRoll.pos);
				var angle: Number = Math.atan2(v1.x, v1.y) - Math.atan2(v2.x, v2.y);
				
				var lmat: Matrix = transform.matrix;
				lmat.translate(-_pRoll.center.x, -_pRoll.center.y);
				lmat.rotate(angle);
				lmat.translate(_pRoll.center.x, _pRoll.center.y);
				transform.matrix = lmat;
				
				setPosNotify();
			}
		}
		
		protected function doCRUp(e: MouseEvent): void {
			if ((_pResize != null) || (_pRoll != null)) {
				_pResize = null;
				_pRoll	 = null;
				if (!parent.hitTestPoint(root.mouseX, root.mouseY)) doOut(e);
			}
		}
		
		protected function setPosNotify(): void {
			parent.dispatchEvent(new ObjectEvent(uip_events.UPDATEMATRIX, getPosMatrix()));
		}
		
		protected function doDrag(e: Event): void {
			setPosNotify();
			if (image.matrix.getScale() > 1) image.dispatchEvent(new ObjectEvent(uip_events.SCALE_RECT, 0));
			updateCtrlRect();
		}		
	}
}